/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package Control;

import Control.exceptions.NonexistentEntityException;
import Control.exceptions.PreexistingEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import Entidades.Firma;
import java.util.ArrayList;
import java.util.List;
import Entidades.Tarjeta;
import Entidades.TipoTarjeta;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

/**
 *
 * @author USUARIO
 */
public class TipoTarjetaJpaController implements Serializable {

    public TipoTarjetaJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(TipoTarjeta tipoTarjeta) throws PreexistingEntityException, Exception {
        if (tipoTarjeta.getFirmaList() == null) {
            tipoTarjeta.setFirmaList(new ArrayList<Firma>());
        }
        if (tipoTarjeta.getTarjetaList() == null) {
            tipoTarjeta.setTarjetaList(new ArrayList<Tarjeta>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Firma> attachedFirmaList = new ArrayList<Firma>();
            for (Firma firmaListFirmaToAttach : tipoTarjeta.getFirmaList()) {
                firmaListFirmaToAttach = em.getReference(firmaListFirmaToAttach.getClass(), firmaListFirmaToAttach.getIdFirma());
                attachedFirmaList.add(firmaListFirmaToAttach);
            }
            tipoTarjeta.setFirmaList(attachedFirmaList);
            List<Tarjeta> attachedTarjetaList = new ArrayList<Tarjeta>();
            for (Tarjeta tarjetaListTarjetaToAttach : tipoTarjeta.getTarjetaList()) {
                tarjetaListTarjetaToAttach = em.getReference(tarjetaListTarjetaToAttach.getClass(), tarjetaListTarjetaToAttach.getNroTransaccion());
                attachedTarjetaList.add(tarjetaListTarjetaToAttach);
            }
            tipoTarjeta.setTarjetaList(attachedTarjetaList);
            em.persist(tipoTarjeta);
            for (Firma firmaListFirma : tipoTarjeta.getFirmaList()) {
                firmaListFirma.getTipoTarjetaList().add(tipoTarjeta);
                firmaListFirma = em.merge(firmaListFirma);
            }
            for (Tarjeta tarjetaListTarjeta : tipoTarjeta.getTarjetaList()) {
                TipoTarjeta oldTipoOfTarjetaListTarjeta = tarjetaListTarjeta.getTipo();
                tarjetaListTarjeta.setTipo(tipoTarjeta);
                tarjetaListTarjeta = em.merge(tarjetaListTarjeta);
                if (oldTipoOfTarjetaListTarjeta != null) {
                    oldTipoOfTarjetaListTarjeta.getTarjetaList().remove(tarjetaListTarjeta);
                    oldTipoOfTarjetaListTarjeta = em.merge(oldTipoOfTarjetaListTarjeta);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findTipoTarjeta(tipoTarjeta.getIdTipo()) != null) {
                throw new PreexistingEntityException("TipoTarjeta " + tipoTarjeta + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(TipoTarjeta tipoTarjeta) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoTarjeta persistentTipoTarjeta = em.find(TipoTarjeta.class, tipoTarjeta.getIdTipo());
            List<Firma> firmaListOld = persistentTipoTarjeta.getFirmaList();
            List<Firma> firmaListNew = tipoTarjeta.getFirmaList();
            List<Tarjeta> tarjetaListOld = persistentTipoTarjeta.getTarjetaList();
            List<Tarjeta> tarjetaListNew = tipoTarjeta.getTarjetaList();
            List<Firma> attachedFirmaListNew = new ArrayList<Firma>();
            for (Firma firmaListNewFirmaToAttach : firmaListNew) {
                firmaListNewFirmaToAttach = em.getReference(firmaListNewFirmaToAttach.getClass(), firmaListNewFirmaToAttach.getIdFirma());
                attachedFirmaListNew.add(firmaListNewFirmaToAttach);
            }
            firmaListNew = attachedFirmaListNew;
            tipoTarjeta.setFirmaList(firmaListNew);
            List<Tarjeta> attachedTarjetaListNew = new ArrayList<Tarjeta>();
            for (Tarjeta tarjetaListNewTarjetaToAttach : tarjetaListNew) {
                tarjetaListNewTarjetaToAttach = em.getReference(tarjetaListNewTarjetaToAttach.getClass(), tarjetaListNewTarjetaToAttach.getNroTransaccion());
                attachedTarjetaListNew.add(tarjetaListNewTarjetaToAttach);
            }
            tarjetaListNew = attachedTarjetaListNew;
            tipoTarjeta.setTarjetaList(tarjetaListNew);
            tipoTarjeta = em.merge(tipoTarjeta);
            for (Firma firmaListOldFirma : firmaListOld) {
                if (!firmaListNew.contains(firmaListOldFirma)) {
                    firmaListOldFirma.getTipoTarjetaList().remove(tipoTarjeta);
                    firmaListOldFirma = em.merge(firmaListOldFirma);
                }
            }
            for (Firma firmaListNewFirma : firmaListNew) {
                if (!firmaListOld.contains(firmaListNewFirma)) {
                    firmaListNewFirma.getTipoTarjetaList().add(tipoTarjeta);
                    firmaListNewFirma = em.merge(firmaListNewFirma);
                }
            }
            for (Tarjeta tarjetaListOldTarjeta : tarjetaListOld) {
                if (!tarjetaListNew.contains(tarjetaListOldTarjeta)) {
                    tarjetaListOldTarjeta.setTipo(null);
                    tarjetaListOldTarjeta = em.merge(tarjetaListOldTarjeta);
                }
            }
            for (Tarjeta tarjetaListNewTarjeta : tarjetaListNew) {
                if (!tarjetaListOld.contains(tarjetaListNewTarjeta)) {
                    TipoTarjeta oldTipoOfTarjetaListNewTarjeta = tarjetaListNewTarjeta.getTipo();
                    tarjetaListNewTarjeta.setTipo(tipoTarjeta);
                    tarjetaListNewTarjeta = em.merge(tarjetaListNewTarjeta);
                    if (oldTipoOfTarjetaListNewTarjeta != null && !oldTipoOfTarjetaListNewTarjeta.equals(tipoTarjeta)) {
                        oldTipoOfTarjetaListNewTarjeta.getTarjetaList().remove(tarjetaListNewTarjeta);
                        oldTipoOfTarjetaListNewTarjeta = em.merge(oldTipoOfTarjetaListNewTarjeta);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = tipoTarjeta.getIdTipo();
                if (findTipoTarjeta(id) == null) {
                    throw new NonexistentEntityException("The tipoTarjeta with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            TipoTarjeta tipoTarjeta;
            try {
                tipoTarjeta = em.getReference(TipoTarjeta.class, id);
                tipoTarjeta.getIdTipo();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The tipoTarjeta with id " + id + " no longer exists.", enfe);
            }
            List<Firma> firmaList = tipoTarjeta.getFirmaList();
            for (Firma firmaListFirma : firmaList) {
                firmaListFirma.getTipoTarjetaList().remove(tipoTarjeta);
                firmaListFirma = em.merge(firmaListFirma);
            }
            List<Tarjeta> tarjetaList = tipoTarjeta.getTarjetaList();
            for (Tarjeta tarjetaListTarjeta : tarjetaList) {
                tarjetaListTarjeta.setTipo(null);
                tarjetaListTarjeta = em.merge(tarjetaListTarjeta);
            }
            em.remove(tipoTarjeta);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<TipoTarjeta> findTipoTarjetaEntities() {
        return findTipoTarjetaEntities(true, -1, -1);
    }

    public List<TipoTarjeta> findTipoTarjetaEntities(int maxResults, int firstResult) {
        return findTipoTarjetaEntities(false, maxResults, firstResult);
    }

    private List<TipoTarjeta> findTipoTarjetaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(TipoTarjeta.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public TipoTarjeta findTipoTarjeta(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(TipoTarjeta.class, id);
        } finally {
            em.close();
        }
    }

    public int getTipoTarjetaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<TipoTarjeta> rt = cq.from(TipoTarjeta.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
